package com.cheer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cheer.bo.LotteryBO;
import com.cheer.common.Constant;
import com.cheer.dao.*;
import com.cheer.entity.ExMatchAwardEntity;
import com.cheer.entity.ExMatchAwardRecordEntity;
import com.cheer.entity.ExMatchUserEntity;
import com.cheer.entity.OaUserEntity;
import com.cheer.enums.LotteryActTypeEnum;
import com.cheer.exception.ServiceException;
import com.cheer.service.*;
import com.cheer.utils.BeanUtil;
import com.cheer.vo.LotteryPrizeVO;
import com.cheer.vo.LotteryUserInfoVO;
import com.cheer.vo.PrizeListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * @author cheer
 */
@Service
@Slf4j
public class LotteryServiceImpl implements LotteryService {

    @Autowired
    private ExMatchAwardDao exMatchAwardDao;

    @Autowired
    private ExMatchAwardRecordDao exMatchAwardRecordDao;

    @Autowired
    private PrizeCacheDao prizeCacheDao;

    @Autowired
    private LotteryCacheDao lotteryCacheDao;

    @Autowired
    private OaUserService oaUserService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private IntegralConsumeService integralConsumeService;

    @Autowired
    private CacheService cacheService;

    @Autowired
    private AuthService authService;

    @Override
    public List<String> getLotteryAnnouncement() {
        return lotteryCacheDao.getAnnouncement();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public LotteryPrizeVO startLottery(HttpSession session) {
        // 抽奖机会
        OaUserEntity oaUser = oaUserService.getByOpenid(authService.getOpenid(session));
        ExMatchUserEntity user = authService.getExUserByOpenId(session, oaUser);
        // 获取用户剩余次数
        cacheService.decUserExchangeTime(oaUser);
        // 抽奖
        LotteryPrizeVO lotteryVO = lotteryAlgorithm(user.getId());
        if (lotteryVO.getIsLucky() == false) {
            return lotteryVO;
        }
        // 插入中奖记录
        ExMatchAwardRecordEntity awardRecord = new ExMatchAwardRecordEntity();
        awardRecord.setUserId(user.getId());
        awardRecord.setAwardId(lotteryVO.getAwardId());
        exMatchAwardRecordDao.insert(awardRecord);

        // 奖品为积分单独处理
        ExMatchAwardEntity award = exMatchAwardDao.selectById(awardRecord.getAwardId());
        if(award.getIsIntegral()){
            oaUser.addIntegral(award.getUnitQuantity());
            oaUserService.updateById(oaUser);
        }
        return lotteryVO;
    }

    private LotteryPrizeVO lotteryAlgorithm(Long userId) {

        LotteryPrizeVO lotteryPrizeVO = new LotteryPrizeVO();
        Integer randomBlockIndex = systemConfigService.getRandomBlockIndex();
        ExMatchAwardRecordEntity awardRecord = exMatchAwardRecordDao
                .selectOne(new QueryWrapper<ExMatchAwardRecordEntity>()
                .eq("user_id", userId).last("limit 1"));
        if (awardRecord != null) {
            lotteryPrizeVO.setIsLucky(false);
            lotteryPrizeVO.setPrizeIndex(randomBlockIndex);
            lotteryPrizeVO.setAwardId(0L);
            return lotteryPrizeVO;
        }
        String awardId = prizeCacheDao.getPrize();
        if (awardId == null) {
            lotteryPrizeVO.setIsLucky(false);
            lotteryPrizeVO.setPrizeIndex(randomBlockIndex);
            lotteryPrizeVO.setAwardId(0L);
            return lotteryPrizeVO;
        }else{
            Integer index = exMatchAwardDao.selectById(awardId).getIndex();
            lotteryPrizeVO.setIsLucky(true);
            lotteryPrizeVO.setPrizeIndex(index);
            lotteryPrizeVO.setAwardId(Long.valueOf(awardId));
            return lotteryPrizeVO;
        }
    }

    @Override
    public String getLotteryRecord(Long userId) {
        ExMatchAwardRecordEntity awardRecord = exMatchAwardRecordDao.selectOne(new QueryWrapper<ExMatchAwardRecordEntity>()
                .eq("user_id", userId).last("limit 1"));
        if (awardRecord != null) {
            ExMatchAwardEntity award = exMatchAwardDao.selectById(awardRecord.getAwardId());
            if (award != null) {
                return award.getAwardName();
            }
        }
        return null;
    }

    @Override
    public List<PrizeListVO> prizeList() {

        List<ExMatchAwardEntity> awardList = exMatchAwardDao.selectList(new QueryWrapper<ExMatchAwardEntity>()
                .lambda().eq(ExMatchAwardEntity::getAtc, LotteryActTypeEnum.INTEGRAL.getCode()));
        return BeanUtil.batchTransform(PrizeListVO.class, awardList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer exchange(String openid) {

        // 兑换次数
        Integer exchangeNum = 1;
        // 兑换积分
        OaUserEntity oaUser = oaUserService.getByOpenid(openid);
        // 查询用户今日兑换次数
        Integer exchangeTime = integralConsumeService.getExchangeTime(oaUser.getId());
        Integer maxExchangeTime = Integer.valueOf( systemConfigService
                .getConfigValueByKey(SystemConfigServiceImpl.INT_EXCHANGE_TIME ));
        if( exchangeTime >= maxExchangeTime ){
            throw new ServiceException("今日兑换已达到上限！");
        }
        Integer shopCredit = oaUser.getShopCredit();
        // 获取每次消耗积分
        Integer exchange = systemConfigService.getIntExchange();
        if(shopCredit > exchange){
            oaUserService.consumeCredit(oaUser.getId(), exchange);
        }else{
            throw new ServiceException("您的可用积分不足！");
        }
        // 插入兑换积分表
        integralConsumeService.save(oaUser.getId(), exchange, exchangeNum, LotteryActTypeEnum.QUESTION);
        // 缓存中增加今日次数
        cacheService.addUserExchangeTime(oaUser);
        // 返回剩余次数
        return ( maxExchangeTime - exchangeTime ) - 1;
    }

    @Override
    public LotteryUserInfoVO userInfo(String openid) {

        OaUserEntity oaUser = oaUserService.getByOpenid(openid);
        Integer exchangeTime = cacheService.getExchangeTime(oaUser);
        Integer consumeIntegrate = systemConfigService.getIntExchange();

        return new LotteryUserInfoVO(exchangeTime, consumeIntegrate);
    }

}
